package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
@PropertySource(value = "classpath:/properties/image.properties",encoding = "utf-8")
public class FileServiceImpl implements FileService{
    @Value("${image.dirPath}")
    private String dirPath;
    @Value("${image.urlPath}")
    private String urlPath;

    //为了防止Set集合每次都要创建,则通过static代码块的形式封装数据
    private static Set<String> imageSet = new HashSet<>();


    static {
        imageSet.add(".jpg");
        imageSet.add(".png");
        imageSet.add(".gif");
    }

    /**
     * 文件上传具体步骤:
     *      1.如何校验用户上传的是图片  jpg|png
     *      2.如何防止用户上传恶意程序  木马.exe.jpg  宽度*高度
     *      3.应该采用分目录存储的方式  保存数据
     *      4.上传的文件名称应该尽量避免重名   自定义文件名称     UUID.后缀...
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //1.校验图片类型是否正确      1.正则表达式判断   2.准备集合之后进行校验Set<去重>
        //1.1获取上传的图片类型
        String filename = uploadFile.getOriginalFilename();//文件的全名abc.jpg
        filename = filename.toLowerCase();                 //将所有的字符转化为小写
        int index = filename.lastIndexOf(".");
        String fileType = filename.substring(index);    //含头不含尾
        //1.2判断是否为图片类型  bug

        if(!imageSet.contains(fileType)){
            //用户上传的不是图片
            return ImageVO.fail();
        }

        //2.上传的数据是否为恶意程序,高度和宽度是否为null   利用图片API
        //BufferedImage对象 专门负责封装图片
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return ImageVO.fail();
            }

            //3.采用分目录存储的方式
            //3.1 分目录存储方式1 hash方式 AABBCCDD
            //3.1 分目录存储方式2 时间方式存储 yyyy/MM/dd
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //3.2 准备文件存储的目录
            String imageDir = dirPath + dateDir;
            File imageFileDir = new File(imageDir);
            if (!imageFileDir.exists()) {
                imageFileDir.mkdirs();
            }

            //4.实现文件上传
            //4.1 动态拼接文件名称 uuid.后缀
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid+fileType;
            //4.2准备文件上传的全路径 磁盘路径地址+文件名称
            File imageFile = new File(imageDir+realFileName);
            //4.3实现文件的上传
            /**
             * 请求协议：http:// https:// 不带证书，带证书
             *
             */
            uploadFile.transferTo(imageFile);
            //拼接url地址和文件地址，文件名称
            String url = urlPath+dateDir+realFileName;
            System.out.println("上传成功");
            return ImageVO.success(url,width,height);

        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail();
        }

    }
}
